{ INFORMATICS.MCCME.RU
  Problem statement: http://informatics.mccme.ru/moodle/mod/statements/view3.php?chapterid=638
  Verdict: Accepted
}
type point = record
     x,y:longint;
end;
 
var
   i,n,k:longint;
	 a,b:array[0..30010] of point;
	 r:double;
 
procedure swap(var a,b:point);
var
	 t:point;
begin
t:=a;
a:=b;
b:=t;
end;
 
procedure convexHull(a:array of point; n:longint; var b:array of point; var k:longint);
var
	up,down:array[0..30010] of point;
	u,d,i:longint;
	p1,p2:point;
 
	procedure sort(l,r:longint);
	var
		i,j:longint;
		x:point;
	begin
	i:=l;
	j:=r;
	x:=a[(l+r) div 2]; 
	repeat
				while (a[i].x<x.x) or ((a[i].x=x.x) and (a[i].y<x.y)) do inc(i);
				while (a[j].x>x.x) or ((a[j].x=x.x) and (a[j].y>x.y)) do dec(j);
				if i<=j then begin
					swap(a[i],a[j]);
					inc(i);
					dec(j);
				end;
	until i>j;
	if l<j then sort(l,j);
	if i<r then sort(i,r);
	end;     
 
	function cw(a,b,c:point):boolean;
	begin
	result:=a.x*(b.y-c.y)+b.x*(c.y-a.y)+c.x*(a.y-b.y)<0;
	end;
 
	function ccw(a,b,c:point):boolean;
	begin
	result:=a.x*(b.y-c.y)+b.x*(c.y-a.y)+c.x*(a.y-b.y)>0;
	end;
 
begin
if n=1 then begin
	k:=1;
	b[1]:=a[1];
	exit;
end;
sort(1,n);
p1:=a[1];
p2:=a[n];
u:=1;
d:=1;
up[1]:=p1;
down[1]:=p1;
for i:=2 to n do begin
	if (i=n) or cw(p1,a[i],p2) then begin
		while (u>=2) and (not cw(up[u-1],up[u],a[i])) do dec(u);
		inc(u);
		up[u]:=a[i];	
	end else 
	if (i=n) or ccw(p1,a[i],p2) then begin
		while (d>=2) and (not ccw(down[d-1],down[d],a[i])) do dec(d);
		inc(d);
		down[d]:=a[i];	
	end;
end;
k:=0;
for i:=1 to u do begin
	inc(k);
	b[k]:=up[i];
end;
for i:=d downto 2 do begin
	inc(k);
	b[k]:=down[i];
end;
end;
 
begin
reset(input,'input.txt');
rewrite(output,'output.txt');
read(n);
for i:=1 to n do read(a[i].x,a[i].y);
convexHull(a,n,b,k);
r:=0;
for i:=2 to k do
	r:=r+sqrt(sqr(b[i].x-b[i-1].x)+sqr(b[i].y-b[i-1].y));
r:=r+sqrt(sqr(b[k].x-b[1].x)+sqr(b[k].y-b[1].y));
writeln(r:0:1);
end.